package interfaces.hud.targetInfos;

import logic.common.player.Player;
import logic.common.player.playerListeners.HunterChangedEvent;
import logic.common.player.playerListeners.KillAssistEvent;
import logic.common.player.playerListeners.KillEvent;
import logic.common.player.playerListeners.MissionAssistEvent;
import logic.common.player.playerListeners.PlayerListener;
import logic.common.player.playerListeners.RespawnEvent;
import logic.common.player.playerListeners.TargetChangedEvent;
import logic.ships.hunter.Hunter;
import logic.status.StatusChangedEvent;
import logic.status.StatusListener;

import networking.messages.syncMessages.ValueType;

import org.fenggui.layout.StaticLayout;
import org.fenggui.util.Color;

import fileHandling.language.interfaces.HUDText;

import interfaces.GUISource;
import interfaces.ImageUpdater;
import interfaces.PropertyContent;
import interfaces.hud.BasicHUD;
import interfaces.hud.spectate.SpectateChangeEvent;
import interfaces.hud.spectate.SpectateListener;
import interfaces.hud.spectate.SpectateWidget;
import interfaces.superWidgets.MinimizeWindow;

public class TargetInfoWindow extends MinimizeWindow implements SpectateWidget {
	
	private Player player;
	private Hunter target;
	private PropertyContent hpContent, shieldContent;
	private int border, propertiesWidth, propertiesHeight, hpY, shieldY;
	private String currentImagePath;
	private ImageUpdater targetImage;
	private StatusListener statusListener;
	private PlayerListener playerListener;
	
	public TargetInfoWindow(BasicHUD hud) {
		super(HUDText.No_Target, Mode.DOWN, hud);
		
		content.setLayoutManager(new StaticLayout());
				
		setXY(0, 0);
		int width = hud.getWidth() / 5;
		int height = hud.getWindowHeight();
		setSize(width, height);

		int contentWidth = content.getWidth();
		int contentHeight = content.getHeight();
		
		border = contentHeight / 24;
		propertiesWidth = contentWidth - (border * 5 / 2);
		propertiesHeight = contentHeight / 13;
		shieldY = contentHeight - 2 * border - 2 * propertiesHeight;
		hpY = shieldY - propertiesHeight;
		
		playerListener = new PlayerListener() {
			@Override
			public void targetChanged(TargetChangedEvent event) {
				setTarget(event.getNewTarget());
			}

			@Override
			public void hunterChanged(HunterChangedEvent event) {}
			@Override
			public void respawned(RespawnEvent event) {}
			@Override
			public void killed(KillEvent event) {}
			@Override
			public void killAssist(KillAssistEvent event) {}
			@Override
			public void missionAssist(MissionAssistEvent event) {}
		};
		
		player = hud.getIngameState().getPlayer();
		hud.addListener(player, playerListener);
		
		init();
		createListener();
		
		layout();
	}
	
	private void init() {
		PropertyContent.Mode mode = PropertyContent.Mode.LEFT;
		
		hpContent = new PropertyContent(propertiesWidth, propertiesHeight, border, hpY, HUDText.Hitpoints, mode);
		hpContent.changeBackgroundColor(Color.BLACK);
		hpContent.changeValueColor(Color.RED);
		
		shieldContent = new PropertyContent(propertiesWidth, propertiesHeight, border, shieldY, HUDText.Shields, mode);
		shieldContent.changeBackgroundColor(Color.BLACK);
		shieldContent.changeValueColor(Color.BLUE);
		
		int imageSize = hpY - border * 2;
		targetImage = new ImageUpdater(border, border, imageSize, imageSize);
	}
	
	private void createListener() {
		statusListener = new StatusListener() {
			@Override
			public void valueChanged(StatusChangedEvent event) {
				ValueType type = event.getType();
				switch(type) {
					case HP: hpContent.setValue(event.getIntValue()); break;
					case Shield: shieldContent.setValue(event.getIntValue()); break;
				}
			}
		};
	}
	
	public void setTarget(Hunter newTarget) {
		assert(newTarget != null);
		
		if(target != null) removeListeners();
		assert(newTarget != null);
		target = newTarget;
		
		if(!content.getContent().contains(hpContent)) content.addWidget(hpContent);
		if(!content.getContent().contains(shieldContent)) content.addWidget(shieldContent);
		if(!content.getContent().contains(targetImage)) content.addWidget(targetImage);
		
		updateImage();
		String buttonString = newTarget.getPilot().getName() + " (" + newTarget.getHunterName() + ")";
		minimizeButton.setText(buttonString);
		setHPColor();
		addListeners();
	}
	
	private void addListeners() {
		assert(target != null);
		target.addStatusListener(statusListener);
		
		hpContent.setMaxValue(target.getMaxHP());
		hpContent.setValue(target.getCurrentHP());
		
		shieldContent.setMaxValue(target.getMaxShield());
		shieldContent.setValue(target.getCurrentShield());
	}
	
	private void removeListeners() {
		assert(target != null);
		target.removeStatusListener(statusListener);
	}
	
	private void updateImage() {
		String imageFile = target.getFilePath() + "/icon.png";
		if(imageFile != currentImagePath) {
			currentImagePath = imageFile;
			targetImage.setImage(currentImagePath);
		}
	}
	
	private void setHPColor() {
		assert(target != null);
		
		Player watchedPlayer = hud.getIngameState().getPlayer();
		
		boolean isTeamMate = watchedPlayer.getTeam() == target.getTeam();
		Color color = (isTeamMate ? GUISource.green : Color.RED);
		hpContent.changeValueColor(color);
	}
	
	@Override
	public SpectateListener getSpectateListener() {
		return new SpectateListener() {
			@Override
			public void spectating(SpectateChangeEvent event) {
				Player newPlayer = event.getWatchedPlayer();
				if(newPlayer != player) {
					player.removePlayerListener(playerListener);
					player = newPlayer;
					hud.addListener(player, playerListener);
					
					if(player.getCurrentTarget() != null) {
						setTarget(player.getCurrentTarget());
						hud.getHUDState().changeMarkedTarget(target);
					}
				}
			}
		};
	}
}